package com.ofek.eventos;

import java.util.ArrayList;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.ofek.applicationbase.broadcast.Delegate;
import com.ofek.applicationbase.forms.FieldQConnector;
import com.ofek.applicationbase.forms.FormFragment;
import com.ofek.applicationbase.forms.QuestionAdapter;
import com.ofek.applicationbase.forms.QuestionView;
import com.ofek.applicationbase.forms.QuestionViewController;
import com.ofek.applicationbase.forms.SimpleQuestionView;
import com.ofek.applicationbase.forms.question.OptionBoxQuestionView;
import com.ofek.applicationbase.utils.Log;
import com.ofek.eventos.db.ContextDatabase;
import com.ofek.eventos.db.ContextWrapper;
import com.ofek.eventos.db.EventosDatabaseService;
import com.ofek.eventos.db.EventosDatabaseService.EventosDatabaseServiceBinder;
import com.ofek.eventos.db.PageWrapper;
import com.ofek.eventos.db.datatypes.EventData;
import com.ofek.eventos.db.datatypes.Field;
import com.ofek.eventos.db.datatypes.Type;
import com.ofek.eventos.db.datatypes.helptypes.ScheduleFieldInEvent;
import com.ofek.eventos.db.datatypes.helptypes.TextFieldInEvent;
import com.ofek.eventos.db.datatypes.predefined.ContextDefiner;
import com.ofek.eventos.db.datatypes.predefined.PageDefiner;
import com.ofek.eventos.db.datatypes.predefined.SearchScheme;

public class FormActivity extends FragmentActivity {
	public static final String INTENT_KEY_EXTRA_DATA = "INTENT_KEY_EXTRA_DATA";
	public static final String ACTION_FORM_EVENT = "EVENT_FORM";
	public static final String ACTION_FORM_PAGE = "FORM_PAGE";
	public static final String ACTION_FORM_CONTEXT = "ACTION_FORM_CONTEXT";
	protected static final String INTENT_KEY_EXTRA_ACTION = "INTENT_KEY_EXTRA_ACTION";

	@Override
	protected void onCreate(final Bundle savedInstanceState) {
		Log.d(this + " "+"onCreate");
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_form);

		final String action = getIntent().getExtras().getString(INTENT_KEY_EXTRA_ACTION);
		changeFrgment(action.equals(ACTION_FORM_EVENT) ? new EventFragment() :
			action.equals(ACTION_FORM_PAGE) ? new PageDefinerFragment() :
				action.equals(ACTION_FORM_CONTEXT) ? new ContextDefinerFragment() : null);
	}

	protected void changeFrgment(final Fragment fragment) {
		final FragmentManager fragmentManager = getSupportFragmentManager();
		final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
		fragmentTransaction.replace(R.id.container, fragment);
		fragmentTransaction.commit();
	}
	public static class ContextDefinerFragment extends EventosFormFragment {

		private ContextWrapper ctxDef;
		@Override 
		protected ArrayList<QuestionViewController> createQuestions() {
			final ArrayList<QuestionViewController> createQuestions = new ArrayList<QuestionViewController>();
			ctxDef = (ContextWrapper) getActivity().getIntent().getSerializableExtra(INTENT_KEY_EXTRA_DATA);
			if (ctxDef==null) ctxDef = new ContextScheme();
			try {
				createQuestions.add(0,new FieldQConnector("name", ctxDef, new SimpleQuestionView(R.string.title,InputType.TYPE_CLASS_TEXT,getActivity(),true )));
			} catch (final Exception e) {
				e.printStackTrace();
			} 
			return createQuestions;
		}
		@Override
		public void onFormSubmitted() {
			ContextDatabase.getInstance().add(ctxDef);
			getActivity().finish();
		}
		public static class ContextScheme extends ContextWrapper {
			public String name;

			@Override
			public String getName(final Context c) {
				return name;
			}

		}

	}
	public static class PageDefinerFragment extends SearchDefinerFragment {

		private PageDefiner pageDefiner;
		private ContextDefiner ctxDef;
		@Override 
		protected ArrayList<QuestionViewController> createQuestions() {

			try {
				ctxDef = (ContextDefiner) getActivity().getIntent().getSerializableExtra(INTENT_KEY_EXTRA_DATA);
				pageDefiner = new NewPageDefiner(searchData);
			} catch(final Exception e) {
				final PageWrapper pW = (PageWrapper) getActivity().getIntent().getSerializableExtra(INTENT_KEY_EXTRA_DATA);
				pageDefiner = pW.getPageDefiner();
				if ( pageDefiner instanceof NewPageDefiner ) {
					searchData = ((NewPageDefiner)pageDefiner).searchScheme;
				} else {
					searchData.careForTime = pageDefiner.careForTime();
					searchData.from = pageDefiner.getStart();
					searchData.owner = pageDefiner.getOwner();
					searchData.startWith = pageDefiner.getStartsWith();
					searchData.to = pageDefiner.getEnd();
					searchData.type = eventosService.getType(pageDefiner.getTypeId());
					if ( searchData.type == null ) 
						searchData.type = eventosService.getType(pageDefiner.getDefaultTypeId());
				}
				ctxDef = pW.getParent();
			}
			final ArrayList<QuestionViewController> createQuestions = super.createQuestions();
			try {
				createQuestions.add(0,new FieldQConnector("pageTitle", pageDefiner, new SimpleQuestionView(R.string.page_title,InputType.TYPE_CLASS_TEXT,getActivity(),true )));
				createQuestions.add(1,new FieldQConnector("pageSubTitle", pageDefiner, new SimpleQuestionView(R.string.page_subtitle,InputType.TYPE_CLASS_TEXT,getActivity(),false )));
			} catch (final Exception e) {
				e.printStackTrace();
			} 
			return createQuestions;
		}
		@Override
		public void onFormSubmitted() {
			ctxDef.add(pageDefiner);
			getActivity().finish();
		}
		public static class NewPageDefiner implements PageDefiner {
			/**
			 * 
			 */
			private static final long serialVersionUID = -6621450457147530029L;
			public String pageTitle,pageSubTitle;
			private final SearchScheme searchScheme;

			public NewPageDefiner(final SearchScheme searchData) {
				searchScheme = searchData;
			}
			@Override
			public String getStartsWith() {
				return searchScheme.getStartsWith();
			}
			@Override
			public long getStart() {
				return searchScheme.getStart();
			}
			@Override
			public Long getTypeId() {
				return searchScheme.getTypeId();
			}
			@Override
			public boolean careForTime() {
				return searchScheme.careForTime();
			}
			//			@Override
			//			public boolean equals(final Object o) {
			//				return searchScheme.equals(o);
			//			}
			@Override
			public long getEnd() {
				return searchScheme.getEnd();
			}
			@Override
			public String getOwner() {
				return searchScheme.getOwner();
			}
			@Override
			public int hashCode() {
				return searchScheme.hashCode();
			}
			@Override
			public String toString() {
				return searchScheme.toString();
			}
			@Override
			public String getPageTitle(final Context c) {
				return pageTitle;
			}

			@Override
			public String getPageSubTitle(final Context c) {
				return pageSubTitle;
			}
			@Override
			public Long getDefaultTypeId() {
				return searchScheme.getTypeId();
			}

		}

	}
	public static class EventFragment extends FormFragment implements ServiceConnection {
		private ArrayList<Type> types;
		private EventData event;
		private boolean create;

		@Override
		public void onCreate(final Bundle savedInstanceState) {
			Log.d(this + " "+"onCreate");
			super.onCreate(savedInstanceState);

		}
		/* (non-Javadoc)
		 * @see com.ofek.applicationbase.forms.FormFragment#onActivityCreated(android.os.Bundle)
		 */
		@Override
		public void onActivityCreated(final Bundle savedInstanceState) {
			super.onActivityCreated(savedInstanceState);
			create = true;
			try {
				event = (EventData) getActivity().getIntent().getSerializableExtra(INTENT_KEY_EXTRA_DATA);
				create = false;
			} catch (final ClassCastException e) {}
			final TextView header = (TextView)getActivity().findViewById(R.id.header_text);
			final TextView subheader = (TextView)getActivity().findViewById(R.id.sub_header_text);
			header.setText(event!=null ? R.string.edit_event : R.string.create_event);
			subheader.setVisibility(View.INVISIBLE);
			if (savedInstanceState != null)   {
				event = (EventData) savedInstanceState.getSerializable(INTENT_KEY_EXTRA_DATA);
				Log.d(this +" restoring "+event.values);

			}
			setHasOptionsMenu(true);
		}

		@Override
		public void onCreateOptionsMenu(final Menu menu,final MenuInflater inflater) {
			inflater.inflate(R.menu.page_menu, menu);
		}
		//		@Override
		//		public boolean onOptionsItemSelected(final MenuItem item) {
		//			if ( item.getItemId()==R.id.action_edit ) 
		//				EventosAndroidUtils.startFormActivity(this,FormActivity.ACTION_FORM_PAGE,currentPageDefiner);
		//			if ( item.getItemId()==R.id.action_add ) 
		//				EventosAndroidUtils.startFormActivity(this,FormActivity.ACTION_FORM_PAGE,contextDefiner);
		//			if ( item.getItemId()==R.id.action_delete ) {
		//				contextDefiner.remove(currentPageDefiner);
		//				mPagerAdapter.notifyDataSetChanged();
		//				if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
		//					recreate();
		//				} else {
		//					finish();
		//					startActivity(getIntent());
		//				}
		//			}
		//			return true;
		//		}
		private EventosDatabaseService eventosService;
		@Override
		public void onServiceConnected(final ComponentName arg0, final IBinder binder) {
			Log.d(this + " "+"onServiceConnected");
			final EventosDatabaseServiceBinder eventosbinder = (EventosDatabaseServiceBinder)binder;
			eventosService = eventosbinder.getEventosService();
			types = eventosService.getTypes();
			if (event==null)   {
				event = new EventData();
				final PageDefiner pageDefiner = (PageDefiner) getActivity().getIntent().getSerializableExtra(INTENT_KEY_EXTRA_DATA);
				event.uid_owner = pageDefiner.getOwner();
				event.uid_creator=EventosApplication.EVENTOS_USER.id;
				event.t = eventosService.getType(pageDefiner.getTypeId());
				if ( event.t==null )
					event.t = eventosService.getType(pageDefiner.getDefaultTypeId());
				for (final Field f : event.t.typeFields.values()) {
					switch (f.fieldType) {
					case Schedule : 
						if (pageDefiner.careForTime()) 
							event.values.put(f.fid,new ScheduleFieldInEvent(event.eid,f.fid,pageDefiner.getStart(),pageDefiner.getEnd(),ScheduleFieldInEvent.NO_REPEAT,ScheduleFieldInEvent.INDEFENITE));
						else 
							event.values.put(f.fid, new ScheduleFieldInEvent(f.fid));
						break;
					case Text: 
						event.values.put(f.fid, new TextFieldInEvent(f.fid));
						break;
					}
				}				
			}
			initForm();
		}

		@Override
		public void onResume() {
			getActivity().bindService(new Intent(getActivity(),EventosDatabaseService.class), this, Context.BIND_AUTO_CREATE);
			super.onResume();
		}
		@Override
		public void onPause() {
			getActivity().unbindService(this);
			super.onPause();
		}
		@Override
		public void onSaveInstanceState(final Bundle outState) {
			Log.d(this +" saving "+event.values);
			super.onSaveInstanceState(outState);
			outState.putSerializable(INTENT_KEY_EXTRA_DATA,event);
		}
		@Override
		public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
				final Bundle savedInstanceState) {
			Log.d(this + " "+"onCreateView");
			return super.onCreateView(inflater, container, savedInstanceState);

		}
		@Override
		public void onFormSubmitted() {
			if (!create) 
				eventosService.update(event);
			else  
				eventosService.add(event);
			getActivity().finish();
		}
		/* (non-Javadoc)
		 * @see com.ofek.applicationbase.forms.FormFragment#onQuestionAdapterInited(com.ofek.applicationbase.forms.QuestionAdapter)
		 */
		@Override
		protected void onQuestionAdapterInited(final QuestionAdapter qAdapter) {
		}

		@Override
		protected ArrayList<QuestionViewController> createQuestions() {
			Log.d(this + " "+"createQuestions");
			final OptionBoxQuestionView optionBoxQuestionView = new OptionBoxQuestionView(R.string.event_type, getActivity(),types.toArray(new Type[types.size()]));
			optionBoxQuestionView.registerAnswerChangedListener(new Delegate<Object>() {

				@Override
				public void invoke(final Object t) {
					if ( !t.equals(event.t) ) {
						Log.d("Changed Type from " + event.t + " to " + t);
						event.t = (Type) t;
						event.values.clear();
						initForm();
					}


				}
			});

			final ArrayList<QuestionViewController> arrayList = new ArrayList<QuestionViewController>();
			try {
				arrayList.add(new FieldQConnector("t", event, optionBoxQuestionView));
				for (final Long f : event.values.keySet()) 
					addField(eventosService.getField(f.longValue()),arrayList);

			} catch (final Exception e) {
				e.printStackTrace();
			}
			return arrayList;
		}

		/**
		 * @param f
		 * @param arrayList 
		 * @throws Exception 
		 */
		private void addField(final Field f, final ArrayList<QuestionViewController> arrayList) throws Exception {
			final Object object = event.values.get(f.fid);
			switch (f.fieldType) {
			case Schedule : 
				if (object==null)
					event.values.put(f.fid, new ScheduleFieldInEvent(f.fid));
				final ScheduleQuestionView scheduleQuestionView = new ScheduleQuestionView(getActivity());
				arrayList.add(new ValueConnector(f,event,scheduleQuestionView)); 
				break;
			case Text: 
				if (object==null)
					event.values.put(f.fid, new TextFieldInEvent(f.fid));
				final TextQuestionView simpleQuestionView = new TextQuestionView(f.title,InputType.TYPE_CLASS_TEXT, getActivity(), f.isRequiered);
				arrayList.add(new ValueConnector(f,event,simpleQuestionView)); 
				break;
			}
		}

		private class ValueConnector extends QuestionViewController {


			protected final Field field;
			private final EventData whereToPutResults;


			public ValueConnector(final Field field, final EventData whereToPutResults,final QuestionView toControl) throws NoSuchFieldException,
			IllegalArgumentException, IllegalAccessException {
				super(toControl);
				this.field = field;
				this.whereToPutResults = whereToPutResults;
				setDefaultAnswer(whereToPutResults.values.get(field.fid));

			}


			@Override
			protected void onAnswerChanged(final Object t) {
				whereToPutResults.values.put(field.fid, t);
			}
		}
		@Override
		public void onServiceDisconnected(final ComponentName name) {
			// TODO Auto-generated method stub

		}
	}
}
